/**************************************************************************************************
Filename:       NewBit_Demo.c
Editor:         Tome @ newbit
Revised:        $Date: 2017/2/15 11:20:02 +0800  $
Revision:       $Revision: 00001 $

Description:    
History:        
Notes:          

**************************************************************************************************/



/**************************************************************************************************
// INCLUDES
**************************************************************************************************/
#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"

#include "NewBit_Demo.h"
#include "DebugTrace.h"

#if !defined( WIN32 )
#include "OnBoard.h"
#endif

#include "ul_strings.h"

/* HAL */
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_uart.h"
#include "hal_dht11.h"

#include "hal_timer1_pwm.h"


/**************************************************************************************************
// TYPEDEF
**************************************************************************************************/



/**************************************************************************************************
// CONSTANTS
**************************************************************************************************/
#define TASK_ID_SELF NewbitDemo_TaskID


#define TEMP_ERR_CODE    0xF0



// This list should be filled with Application specific Cluster IDs.
const cId_t NewbitDemo_ClusterList[NEWBITDEMO_MAX_CLUSTERS] =
{
  NEWBITDEMO_CLUSTERID_REPORT
};

const SimpleDescriptionFormat_t NewbitDemo_SimpleDesc =
{
  NEWBITDEMO_ENDPOINT,              //  int Endpoint;
  NEWBITDEMO_PROFID,                //  uint16 AppProfId[2];
  NEWBITDEMO_DEVICEID,              //  uint16 AppDeviceId[2];
  NEWBITDEMO_DEVICE_VERSION,        //  int   AppDevVer:4;
  NEWBITDEMO_FLAGS,                 //  int   AppFlags:4;
  NEWBITDEMO_MAX_CLUSTERS,          //  byte  AppNumInClusters;
  (cId_t *)NewbitDemo_ClusterList,  //  byte *pAppInClusterList;
  NEWBITDEMO_MAX_CLUSTERS,          //  byte  AppNumInClusters;
  (cId_t *)NewbitDemo_ClusterList   //  byte *pAppInClusterList;
};

// This is the Endpoint/Interface description.  It is defined here, but
// filled-in in NewbitDemo_Init().  Another way to go would be to fill
// in the structure here and make it a "const" (in code space).  The
// way it's defined in this sample app it is define in RAM.
endPointDesc_t NewbitDemo_epDesc;


/*********************************************************************
* LOCAL VARIABLES
*/
byte NewbitDemo_TaskID;   // Task ID for internal task/event processing
// This variable will be received when
// NewbitDemo_Init() is called.
devStates_t NewbitDemo_NwkState;


byte NewbitDemo_TransID;  // This is the unique message ID (counter)

afAddrType_t NewbitDemo_DstAddr;

int8 pwmDutyCh3 = 50;  // 1 - 100
int8 pwmDutyCh4 = 50;  // 1 - 100
int8 dutysetp = -1;

/**************************************************************************************************
// FUNCTIONS DECLERATION
**************************************************************************************************/
static void NewbitDemo_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg );
static void NewbitDemo_MessageMSGCB( afIncomingMSGPacket_t *pkt );
static void NewbitDemo_HandleKeys( uint8 shift, uint8 keys );

static void NewbitDemo_ReportSensor(uint8 t);

static void dht11_process(uint8* value);


void choujiang(void);


/**************************************************************************************************
// FUNCTIONS
**************************************************************************************************/


/*********************************************************************
* @fn      NewbitDemo_Init
*
* @brief   Initialization function for the Generic App Task.
*          This is called during initialization and should contain
*          any application specific initialization (ie. hardware
*          initialization/setup, table initialization, power up
*          notificaiton ... ).
*
* @param   task_id - the ID assigned by OSAL.  This ID should be
*                    used to send messages and set timers.
*
* @return  none
*/
void NewbitDemo_Init( uint8 task_id )
{
  NewbitDemo_TaskID = task_id;
  NewbitDemo_NwkState = DEV_INIT;
  NewbitDemo_TransID = 0;
  
  
  
  
  NewbitDemo_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
  NewbitDemo_DstAddr.endPoint = NEWBITDEMO_ENDPOINT;
  NewbitDemo_DstAddr.addr.shortAddr = 0;
  
  
  // Fill out the endpoint description.
  NewbitDemo_epDesc.endPoint = NEWBITDEMO_ENDPOINT;
  NewbitDemo_epDesc.task_id = &NewbitDemo_TaskID;
  NewbitDemo_epDesc.simpleDesc
    = (SimpleDescriptionFormat_t *)&NewbitDemo_SimpleDesc;
  NewbitDemo_epDesc.latencyReq = noLatencyReqs;
  
  // Register the endpoint description with the AF
  afRegister( &NewbitDemo_epDesc );
  
  
  // Update the display
#if defined ( LCD_SUPPORTED )
  
  HalLcdWriteString( "NewBit Demo", HAL_LCD_LINE_1 );
  //HalLcdWriteString( "newbit.com.cn", HAL_LCD_LINE_4 );
  HalLcdWriteString( "newbitstudio", HAL_LCD_LINE_4 );
#endif  
  
  
  // Register for all key events - This app will handle all key events
  RegisterForKeys( TASK_ID_SELF );
  
  
  //osal_start_reload_timer(TASK_ID_SELF, NBD_EVT_DHT11, 1000 ); 
  //osal_start_timerEx(TASK_ID_SELF, NBD_EVT_DHT11, 1000 ); 
  
  //halTimer1PWMInit( PWM_BASE_FREQ_HZ_200 );
  //halTimer1ChannelEnable(HAL_T1PWM_CH3, 1, TRUE);
  //halTimer1ChannelEnable(HAL_T1PWM_CH4, 1, TRUE);
  
  //osal_start_reload_timer(TASK_ID_SELF, NBD_PWM_TEST, 10 ); 
  
  
  osal_start_timerEx(TASK_ID_SELF, NBD_POWERDOWN, 1000 ); 
  
  
  
}








/*********************************************************************
* @fn      NewbitDemo_ProcessEvent
*
* @brief   Generic Application Task event processor.  This function
*          is called to process all events for the task.  Events
*          include timers, messages and any other user defined events.
*
* @param   task_id  - The OSAL assigned task ID.
* @param   events - events to process.  This is a bit map and can
*                   contain more than one event.
*
* @return  none
*/
uint16 NewbitDemo_ProcessEvent( uint8 task_id, uint16 events )
{
  afIncomingMSGPacket_t *MSGpkt;
  
  
  if ( events & SYS_EVENT_MSG )
  {
    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( NewbitDemo_TaskID );
    while ( MSGpkt )
    {
      switch ( MSGpkt->hdr.event )
      {
      case ZDO_CB_MSG:
        NewbitDemo_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
        break;
        
      case KEY_CHANGE:
        NewbitDemo_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
        break;
        
      case AF_DATA_CONFIRM_CMD:
        
        break;
        
      case AF_INCOMING_MSG_CMD:
        NewbitDemo_MessageMSGCB( MSGpkt );
        break;
        
      case ZDO_STATE_CHANGE:
        NewbitDemo_NwkState = (devStates_t)(MSGpkt->hdr.status);
        
        if ( ( NewbitDemo_NwkState == DEV_ROUTER )          
            || ( NewbitDemo_NwkState == DEV_END_DEVICE )  )
          osal_start_reload_timer(TASK_ID_SELF, NBD_EVT_DHT11, 1000 ); 
        
        break;
        
      case ONEBUS_EVENT:
        dht11_process(((oneBusValue_t*)MSGpkt)->value);
        break;
        
      default:
        break;
      }
      
      // Release the memory
      osal_msg_deallocate( (uint8 *)MSGpkt );
      
      // Next
      MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( NewbitDemo_TaskID );
    }
    // return unprocessed events
    return (events ^ SYS_EVENT_MSG);
  }
  
  if ( events & NBD_POWERDOWN )
  {
   
    return ( events ^ NBD_POWERDOWN );
  }
  
  
  if ( events & NBD_EVT_DHT11 )
  {   
    HalOneBusStart( TASK_ID_SELF );
    //osal_start_timerEx(TASK_ID_SELF, NBD_EVT_DHT11, 1000 ); 
    return ( events ^ NBD_EVT_DHT11 );
  }
  
  if ( events & NBD_PWM_TEST )
  {
    uint8 str[] = "RED:  ,GRN:   ";
    
    uint8* p = str + 4;
    *p++ = (pwmDutyCh3 / 10) + '0';
    *p++ = (pwmDutyCh3 % 10) + '0';
    p = str + 11;
    *p++ = (pwmDutyCh4 / 10) + '0';
    *p++ = (pwmDutyCh4 % 10) + '0';
    
    HalLcdWriteString( str, HAL_LCD_LINE_3 );
    
    halTimer1PWMDuty( HAL_T1PWM_CH3 ,pwmDutyCh3);
    halTimer1PWMDuty( HAL_T1PWM_CH4 ,pwmDutyCh4);
   
    
    pwmDutyCh3 += dutysetp;
    pwmDutyCh4 += dutysetp;
    
    
    if ( pwmDutyCh3 == 0 )
      dutysetp = 1;
    
    if ( pwmDutyCh3 == 99 )
      dutysetp = -1;

    
    /*
    if ( pwmDutyCh4 == 0)
      pwmDutyCh3 = 99;
    */
    
    return ( events ^ NBD_PWM_TEST );
  }
  
  
  if ( events & NEWBITDEMO_REPORT_TIMEOUT )
  {
    //NewbitDemo_ReportSensor(20);
    return ( events ^ NEWBITDEMO_REPORT_TIMEOUT );
  }
  
  
  return 0;
  
}




/*********************************************************************
* @fn      NewbitDemo_ProcessZDOMsgs()
*
* @brief   Process response messages
*
* @param   none
*
* @return  none
*/
static void NewbitDemo_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg )
{
  switch ( inMsg->clusterID )
  {
  case End_Device_Bind_rsp:
    
    
    
    break;
    
  default:
    
    break;
  }
  
}






/*********************************************************************
* @fn      NewbitDemo_MessageMSGCB
*
* @brief   Data message processor callback.  This function processes
*          any incoming data - probably from other devices.  So, based
*          on cluster ID, perform the intended action.
*
* @param   none
*
* @return  none
*/
static void NewbitDemo_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
  uint16 addr;
  uint8 t;
  uint8 str[20] = "Rvd:";
  uint8 *p = &str[4];
  uint8 ch;
  uint8 len;
  
  switch ( pkt->clusterId )
  {
  case NEWBITDEMO_CLUSTERID_REPORT:
    addr = pkt->srcAddr.addr.shortAddr;
    ul_sprintWord2Hex(p, addr);
    p += 6;
    
    t = pkt->cmd.Data[0];
    osal_memcpy(p, " T:", 3);
    p += 3;
    ch = t / 10;
    *p++ = ch + '0';
    ch = t % 10;
    *p++ = ch + '0';
    
    *p++ = 0;
    len  = (uint8)(p - str);
    HalUARTWrite(0, str, len);
    
    
    break;
  }
}




/**************************************************************************************************
* @fn      NewbitDemo_ReportSensor
*
* @brief   
*
* @param   uint8* pv
*
* @return  static void
**************************************************************************************************/
static void NewbitDemo_ReportSensor(uint8 t)
{
  uint8 temp = t;//
  
  
  if ( AF_DataRequest( &NewbitDemo_DstAddr, &NewbitDemo_epDesc,
                      NEWBITDEMO_CLUSTERID_REPORT,
                      1,
                      (byte *)&temp,
                      &NewbitDemo_TransID,
                      AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
  {
    // Successfully requested to be sent.
  }
  else
  {
    // Error occurred in request to send.
  }
  
}



/*********************************************************************
* @fn      NewBitDemo_HandleKeys
*
* @brief   Handles all key events for this device.
*
* @param   shift - true if in shift/alt.
* @param   keys - bit field for key events. Valid entries:
*                 HAL_KEY_SW_4
*                 HAL_KEY_SW_3
*                 HAL_KEY_SW_2
*                 HAL_KEY_SW_1
*
* @return  none
*/
static void NewbitDemo_HandleKeys( uint8 shift, uint8 keys )
{
  zAddrType_t dstAddr;
  char keystr[] = "SN ";
  
  // Shift is used to make each button/switch dual purpose.
  if ( shift )
  {
    if ( keys & HAL_KEY_SW_1 )
    {
    }
    if ( keys & HAL_KEY_SW_2 )
    {
    }
    if ( keys & HAL_KEY_SW_3 )
    {
    }
    if ( keys & HAL_KEY_SW_4 )
    {
    }
  }
  else
  {
    if ( keys & HAL_KEY_SW_0 )
    {
      HalOneBusStart( TASK_ID_SELF );
      keystr[1] = '0';
    }
    
    if ( keys & HAL_KEY_SW_1 )
    {
      //choujiang();
      keystr[1] = '1';
    }
    
    if ( keys & HAL_KEY_SW_2 )
    {
      keystr[1] = '2';
    }
    
    if ( keys & HAL_KEY_SW_3 )
    {
      keystr[1] = '3';
    }
    
    if ( keys & HAL_KEY_SW_4 )
    {
      keystr[1] = '4';
    }
    
    if ( keys & HAL_KEY_SW_5 )
    {
      keystr[1] = '5';
    }
    HalLcdWriteString(keystr, HAL_LCD_LINE_4);
  }
}



/******************************************************************************
* @fn        dht11_process
*
* @brief     osal system events handler
*
* @param     
*
* @return    none
*/
static void dht11_process(uint8* value)
{
  // hh.hh,  tt.tt , crc
  //HalUARTWrite(0, value ,5);
  
  char hstr[17] = "HUMI:";
  char tstr[12] = "TEMP:";
  char str[17] = "HUMI:xx TEMP:xx";
  
  char* p = str + 5;
  uint8 t = value[0];
  *p++ = t / 10 + '0';
  *p++ = t % 10 + '0';
  //*p++ = 0;
  
  
  p += 6;
  t = value[2];
  *p++ = t / 10 + '0';
  *p++ = t % 10 + '0';
  *p++ = 0;
  
  HalLcdWriteString(str, HAL_LCD_LINE_3);
  //HalLcdWriteString(tstr, HAL_LCD_LINE_4);
  
  
  if ( ( NewbitDemo_NwkState == DEV_ROUTER )          
      || ( NewbitDemo_NwkState == DEV_END_DEVICE )  )
  {
   
    NewbitDemo_ReportSensor(t);
  }
    
}


/**************************************************************************************************
Copyright 2016 Newbit Studio. All rights reserved.
**************************************************************************************************/



